package graduation.project.mutant.strategy;

import graduation.project.body.Expression;
import graduation.project.body.Mutants;
import graduation.project.body.OriginExpression;
import graduation.project.exception.NonExpressionException;

import java.util.ArrayList;

public class LRFMutantsGen implements MutantsGenerator {

	public Mutants generateMutants(String expression, int mutantsNum) {
		
		try{
			OriginExpression originEx = new OriginExpression(expression);
			return generateMutants(originEx, mutantsNum);
		}catch(NonExpressionException e){
			System.out.println("LRFMutantsGen: the expression is invalid.");
			e.printStackTrace();
		}
		return null;
	}

	public Mutants generateMutants(OriginExpression originEx, int num) {
		
		int count = 0; 
		String model = originEx.getModel();
		String idnf = originEx.getIDNF();
		Mutants result = new Mutants(originEx.getExpression(), "LRF");
		ArrayList<Expression> mutantSet = new ArrayList<Expression>();
		
		StringBuffer mutant = new StringBuffer();
		mutant.append(idnf);
		int beginPos = -1;
		int endPos = -1;
		int termsNum = idnf.split("\\+").length;
		StringBuffer remainLit = new StringBuffer();
		StringBuffer tempTerm = new StringBuffer();
		
		char lit;
		for(int i = 0; i < termsNum; i++){
			beginPos = endPos + 1;
			endPos = idnf.indexOf('+', beginPos);
			if(endPos < 0)
				endPos = idnf.length();
			
			tempTerm.append(idnf.substring(beginPos, endPos));
			mutant.delete(beginPos, endPos);
			remainLit.append(model);
			for(int j = 0; j < tempTerm.length(); j++){
				lit = tempTerm.charAt(j);
				int pos = remainLit.indexOf(lit + "");
				if(pos >= 0)
					remainLit.deleteCharAt(pos);
			}
			
			boolean not = false;
			for(int j = 0; j < tempTerm.length(); j++){
				lit = tempTerm.charAt(j);
				if(lit == '!'){
					lit = tempTerm.charAt(j + 1);
					tempTerm.delete(j, j + 2);
					not = true;
					j++;
				}else
					tempTerm.deleteCharAt(j);
				
				for(int k = 0; k < remainLit.length(); k++){
					try{
						tempTerm.insert(j, remainLit.charAt(k));
						mutant.insert(beginPos, tempTerm.toString());
						mutantSet.add(new Expression(mutant.toString()));
						if(num != -1 && ++count >= num)
							break;
						mutant.delete(beginPos, beginPos + tempTerm.length());
						tempTerm.insert(j, '!');
						mutant.insert(beginPos, tempTerm.toString());
						mutantSet.add(new Expression(mutant.toString()));
						mutant.delete(beginPos, beginPos + tempTerm.length());
						tempTerm.delete(j, j + 2);
						if(num != -1 && ++count >= num)
							break;						
					}catch(NonExpressionException e){
						System.out.println("the String is not valid expression.");
						e.printStackTrace();
					}
				}
				if(not){
					tempTerm.insert(j - 1, "!" + lit);
					not = false;
				}
				else
					tempTerm.insert(j, lit);
				if(num != -1 && count >= num)
					break;
			}
			remainLit.delete(0, remainLit.length());
			mutant.insert(beginPos, tempTerm.toString());
			tempTerm.delete(0, tempTerm.length());
			if(num != -1 && count >= num)
				break;
		}
		
		result.setMutants(mutantSet);
		return result;
	}

}
